package View.JTree;

import java.io.File;
import java.io.FileNotFoundException;

import java.util.concurrent.ExecutionException;
import java.util.logging.Level;
import java.util.logging.Logger;

import javax.swing.JFrame;
import javax.swing.JTree;
import javax.swing.SwingWorker;
import javax.swing.event.TreeExpansionEvent;
import javax.swing.event.TreeExpansionListener;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.TreePath;



/**
 * 文件系统树
 */
public class JFileTree extends JTree {

    public static final boolean DIRECTORY_AND_FILE = true;//含有文件节点
 	public static final boolean DIRECTORY_NO_FILE = false;//不含有文件节点
  	private static final String DESKTOP_EN = "Desktop";
    private static final String DESKTOP_ZH = "桌面";
    private static final String DISK_EN = "Disk";
    private JFileTreeNode systemNode = null;
    private JFileTreeNode rootNode;
    private DefaultTreeModel jFileTreeModel;
    private boolean model;//显示文件或不显示文件

    public JFileTree() throws FileNotFoundException {
        this(DIRECTORY_AND_FILE);
    }

  	public JFileTree(boolean model) {
        this(null, model);
    }

  	public JFileTree(File file) {
        this(file, DIRECTORY_AND_FILE);
    }

    public JFileTree(File file, boolean model) {
        this.model = model;
        putClientProperty("JTree.lineStyle", "Angled");
        //建立默认系统文件树
        if (file == null || !file.exists()) {
            file = new File(System.getProperty("user.home") + File.separator + DESKTOP_EN);
            if (!file.exists()) {
                file = new File(System.getProperty("user.home") + File.separator + DESKTOP_ZH);
            }
            rootNode = systemNode = new JFileTreeNode(file);
        } else {
            rootNode = new JFileTreeNode(file);
        }
        rootNode.expand();
        jFileTreeModel = new DefaultTreeModel(rootNode);
        setModel(jFileTreeModel);
        addTreeExpansionListener(new JTreeExpansionListener());
    }

    public String getPathName(TreePath path) {
        Object o = path.getLastPathComponent();
        if (o instanceof JFileTreeNode) {
            return ((JFileTreeNode) o).file.getAbsolutePath();
        }
        return null;
    }

    /**
     * 文件树节点
     */
    protected class JFileTreeNode extends DefaultMutableTreeNode {
        protected File file;

        protected boolean isDirectory;

        public JFileTreeNode(File file) {
            this.file = file;
            isDirectory = file.isDirectory();
            setUserObject(file);
        }

        @Override
        public boolean isLeaf() {
            if (file == null) {
                return false;
            }
            return !isDirectory;
        }

        @Override
        public String toString() {
            if (file.getParentFile() == null) {
                return DISK_EN + "(" + file.getPath().substring(0, 2) + ")";
            } else {
                return file.getName();
            }
        }

        @Override
        public boolean getAllowsChildren() {
            return isDirectory;
        }



     /**
     * 节点展开
     * @return 展开是否含有子节点
     */
     public boolean expand() {
            this.removeAllChildren();
            if (this.equals(systemNode)) {
                File[] roots = File.listRoots();
                for (int i = 0; i < roots.length; i++) {
                    if (roots[i].exists()) {
                        this.add(new JFileTreeNode(roots[i]));
                    }
                }
            }
            File[] files = file.listFiles();
            if (files == null) {
                return false;
            }
            for (int i = 0; i < files.length; i++) {
                File f = files[i];
                /**
                 * 文件夹必添加
                 * 文件则受系统文件树model控制
                 */
                if (f.isDirectory() || model) {
                    this.add(new JFileTreeNode(f));
                }
            }
            return true;
        }
    }

    protected class JTreeExpansionListener implements TreeExpansionListener {
        public void treeExpanded(TreeExpansionEvent e) {
        	System.out.println(e.getPath().getLastPathComponent());
            JFileTreeNode fileNode = (JFileTreeNode) e.getPath().getLastPathComponent();
            if (fileNode != null) {
                new FileNodeExpansion(fileNode).execute();
            }
        }
        public void treeCollapsed(TreeExpansionEvent e) {
        }
    }

    /**
     * 展开节点的后台线程
     */
    protected class FileNodeExpansion extends SwingWorker<Boolean, Void> {
        private JFileTreeNode node;
        public FileNodeExpansion(JFileTreeNode node) {
            this.node = node;
        }

        @Override
        protected Boolean doInBackground() throws Exception {
            return node.expand();
        }

        @Override
        protected void done() {
            try {
                //节点可以展开
                if (get()) {
                    jFileTreeModel.reload(node);
                }
            } catch (InterruptedException ex) {
                Logger.getLogger(JFileTree.class.getName()).log(Level.SEVERE, null, ex);
            } catch (ExecutionException ex) {
                Logger.getLogger(JFileTree.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
    }

    /**
     * test
     */
//    public static void main(String[] args) {
//    	JFrame jf = new JFrame("JFileTree");
//    	jf.add(new JFileTree(DIRECTORY_NO_FILE));
//    	jf.pack();
//    	jf.setVisible(true);
//    	jf.setDefaultCloseOperation(jf.EXIT_ON_CLOSE);
//    }

}


